#!/usr/bin/python

#importo cosas
import nltk
import glob
import math
import sys
import re
from nltk.corpus import stopwords
import categorias
import os


#defino funciones 

#me devuelve un vector como de palabras y categorias, pero con ceros
def crearVectorCerosParaPalabras(conj_categoria_palabras):
	 return map(lambda cat: map(lambda palabra: 0 ,cat),conj_categoria_palabras)
	 
# funcion que recorre el texto y arma los f_i de Zanette
# conjunto_palabras es un conjunto de conjunto de palabras
def obteneFrecuencias(conj_categoria_palabras, texto):

#creo resultado
	resultado = crearVectorCerosParaPalabras(conj_categoria_palabras)

	for palabra_en_texto in texto:
		#me fijo si es alguna palabra  de alguna categorias
		for categoria in range(0,len(conj_categoria_palabras)):
			for palabra_categoria in range(0,len(conj_categoria_palabras[categoria])):
				if (palabra_en_texto == conj_categoria_palabras[categoria][palabra_categoria]):
					resultado[categoria][palabra_categoria]+=1
				
	return resultado
#devuelve la mediana de una lista
def mediana(lista):
	lista1 = sorted(lista)
	return lista1[len(lista1)/2]

#rutea corrigue la ruta por las barras ultimas
def rutea(ruta):
	if (len(ruta)>0):
		if (ruta[len(ruta)-1]!='/'):
			return (ruta+'/')
		else:
			return ruta
	else: print "Error en ruta de carpeta"
			
#programa que hace todo dado un texto
def porLibro(texto):
	#tokenizo
	tokens = nltk.word_tokenize(texto)

	#saco stopWords
	tokens = filter(lambda w: w not in stopWords,tokens)

	#lematizo
	tokens =  map(lambda w: wnl.lemmatize(w),tokens) 


	#Cantidad total de palabras en el texto 
	cant_palabras = len(tokens)

	#fijo cantidad de palabras por "sector" para usar en Zanette (P en zanette)
	cant_palab_x_sector = 2000

	#fijo dimension del espacio
	dim=6

	#fijo dimensiones del espacio que son conjuntos de palabras
	dim_conj_pal = 2



	vector_f_i=[]
	for i in range(0, (cant_palabras / cant_palab_x_sector)+1):
			porcion_de_tokens = tokens[i*cant_palab_x_sector:(i+1)*cant_palab_x_sector]
			#obtengo frecuencias para ese "sector"
			vector_f_i.append(obteneFrecuencias(conj_categoria_pal,porcion_de_tokens))
			#print i*cant_palab_x_sector,(i+1)*cant_palab_x_sector
		
	#vector que suma la frecuencia de cada palabra (Zanette sumatoria sobre f_i)
	vector_sum_fi = crearVectorCerosParaPalabras(conj_categoria_pal)
	for sector in vector_f_i:
		for cat in range(0,len(sector)):
			for pal in range(0,len(sector[cat])):
				vector_sum_fi[cat][pal]+= sector[cat][pal]

	#p_i de zanette
	vector_p_i= map(lambda sector: map(lambda cat: map(lambda palabra: 0 ,cat),sector) ,vector_f_i)
	for i in range(0,len(vector_f_i)):
			for cat in range(0,len(vector_f_i[i])):
				for pal in range(0,len(vector_f_i[i][cat])):
					if (vector_sum_fi[cat][pal]!=0):
						vector_p_i[i][cat][pal]= float(vector_f_i[i][cat][pal]) / float(vector_sum_fi[cat][pal])


	#ahora falta sacar S de Zanette, para nosotros va a ser como en todo lo anterior un vector de categorias y adentro palabras
	#vector_S = [S("love"),S("kiss"),S("heart")],[S("gun"),S("murder"),S("detective)"]]
	vector_S= crearVectorCerosParaPalabras(conj_categoria_pal)
	for sector in vector_p_i:
		for cat in range(0,len(sector)):
			for pal in range(0,len(sector[cat])):
				pi=sector[cat][pal]
				if pi != 0 :
					vector_S[cat][pal] +=  pi * math.log(pi)
	vector_S  = map(lambda cat: map(lambda pal: abs(pal* (-1/math.log(cant_palab_x_sector))),cat),vector_S)	


	#print "sum f_i",vector_sum_fi, len(vector_sum_fi)
	#print "f_i",vector_f_i, len(vector_f_i)
	#print "p_i",vector_p_i, len(vector_p_i)

	#datos importantes debug
	#print filter(lambda sector: sum(map(lambda cat: sum(cat) ,sector))>0 ,vector_f_i)

	#vector de frecuencias
	vector_freq = map(lambda cat: map(lambda pal: float(pal)/float(cant_palabras),cat), vector_sum_fi)

	resultado_promedios = map(lambda cat: float(sum(cat))/float(len(cat)),vector_S)
		
	return resultado_promedios
	
	
	
	
def porAutor(ruta,numero):
	print "Resolviendo autor:",numero,"en:",ruta+str(numero),
	
	#seteo en cero el total
	total =[]
	for cat in conj_categoria_pal: total.append(0)
	
	#lista de los libros por autor
	ficheros_libros = sorted(os.listdir(ruta+str(numero)))
	print " con ", len(ficheros_libros),"libros"
	
	for libro in ficheros_libros:
		libro =ruta+str(numero)+'/'+str(libro)
		print "\t\t\tLeyendo libro: ", libro
		texto =  open(libro,"r")
		texto = texto.read()
		
		temp = porLibro(texto)
		
		for i in range(0,len(temp)):
			total[i]+= temp[i]
	
	if len(ficheros_libros)!=0:
		total = map(lambda valor: valor/float(len(ficheros_libros)),total)		
	print "autor: ",numero," terminado con exito\n"
	
	res_str = numero+": "+str(total)+"\n"
		
	#escribo en el archivo de resultados
	res = open("resultado", "a+")
	res.write(str(res_str))
	res.close()


#programa	##################################
#lematizador
wnl = nltk.stem.WordNetLemmatizer()
#stopwords
stopWords = stopwords.words('english') + [",","."]


#conjunto de palabras por cada dimension (supongo lematizado)
conj_categoria_pal = categorias.conj_categoria_pal
	


#arranco a leer
print "\n\nLeyendo la carpeta: ",sys.argv[1]," donde estan las carpetas por autor "
ficheros = sorted(os.listdir(str(sys.argv[1])))
print "Se encontraron las siguientes carpetas: ",ficheros,"\n"
map(lambda autor: porAutor(rutea(str(sys.argv[1])),autor),ficheros)




#mo = re.match("(.+)\.txt", nombre_archivo)
#numero_autor=  mo.groups(1)[0]
	










